/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package arraydependentqueue;

/**
 *
 * @author mweya
 */
import arraydependentqueue.NoSuchElementException;
import arraydependentqueue.Node;
public class Queue<AnyType> {
    Node[] queue = null;
    
    public Queue(int size) {
        queue = new Node[size];
    }
    
    public Queue(AnyType data, int size) {
        queue = new Node[size];
    }
    
    public int getFreeSpace() {
        if (queue == null) {
            return 0;
        } else {
            Node currentNode = queue[0];
            try {
                int j = 0;
                while (j<queue.length) {
                    if (currentNode == null) {
                        break;
                    }
                }
                return queue.length-j;
            } catch (Exception e) {
                // The queue is either full or this failed
                System.err.println(e.toString());
                return 0;
            }
        }
    }
    
    public boolean offer(AnyType data) {
        if (queue == null) {
            return false;
        }
        Node toAdd = new Node<>(data);
        int j = 0;
        try {
            while (j<queue.length) {
               if (queue[j] == null) {
                   queue[j] = toAdd;
                   break;
                }
               j = j+1;
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    public void add(AnyType data) {
        Node toAdd = new Node<>(data);
        int j = 0;
        try {
            while (j<queue.length) {
                if (queue[j] == null) {
                    queue[j] = toAdd;
                    break;
                }
                j = j+1;
            }
            queue[j] = toAdd;
        } catch (Exception e) {
            // Nothing to do here
            System.err.println(e);
        }
    }
        
    public AnyType peek() {
        if (queue[0] == null) {
            return (AnyType) null;
        } else {
            return (AnyType) queue[0].getData();
        }
    }
    
    public AnyType element() throws NoSuchElementException {
        if (queue[0] == null) {
            throw new NoSuchElementException();
        } else {
            return (AnyType) queue[0].getData();
        }
    }
    
    public AnyType remove()  throws NoSuchElementException {
        if (queue[0] == null) {
            throw new NoSuchElementException();
        } else {
            Node head = queue[0];
            int j = 0;
            while (j<queue.length-1) {
                queue[j] = queue[j+1];
                j = j+1;
            }
            queue[queue.length-1] = null;
            return (AnyType) head.getData();
        }
    }
    
    public AnyType poll() {
        if (queue[0] == null) {
            return (AnyType) null;
        } else {
            Node head = queue[0];
            int j = 0;
            while (j<queue.length-1) {
                queue[j] = queue[j+1];
                j = j+1;
            } 
            queue[queue.length-1] = null;
            return (AnyType) head.getData();
        }
    }
    
    @Override
    public String toString() {
        int j = 0;
        String out = "\nQueue:";
        if (queue == null) {
            return out;
        }
        while (j<queue.length) {
            Node node = queue[j];
            if (node == null) {
                out = out+"\n"+"null";
            }   else {
                out = out+"\n"+node.getData();
            }
            j = j+1;
        }
        return out;
    }
}